package com.atstudy.headline.web.admin.controller.advertisement.advertiser;

import com.atstudy.headline.entity.AdCampaigns;
import com.atstudy.headline.entity.AdCreatives;
import com.atstudy.headline.entity.Advertisers;
import com.atstudy.headline.enums.BaseStatus;
import com.atstudy.headline.result.Result;
import com.atstudy.headline.web.admin.service.AdCampaignsService;
import com.atstudy.headline.web.admin.service.AdCreativesService;
import com.atstudy.headline.web.admin.service.AdvertisersService;
import com.atstudy.headline.web.admin.vo.ad.AdInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/ad")
public class AdvertiserController {
    @Autowired
    private AdvertisersService advertisersService;

    @Autowired
    private AdCampaignsService adCampaignsService;

    @Autowired
    private AdCreativesService adCreativesService;

    @RequestMapping("/page")
    public Result<IPage<Advertisers>> pageAdInfo(@RequestParam Integer current,
                                                 @RequestParam Integer size,
                                                 AdInfoVo adInfoVo){
        Page<Advertisers> page = new Page<>(current,size);
        LambdaQueryWrapper<Advertisers> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like( adInfoVo.getCompanyName()!=null,Advertisers::getCompanyName,adInfoVo.getCompanyName());
        queryWrapper.eq( adInfoVo.getStatus()!=null,Advertisers::getStatus,adInfoVo.getStatus() );
        IPage<Advertisers> advertisersIPage =advertisersService.page(page,queryWrapper);
        return Result.ok(advertisersIPage);
    }

    /**
     * 增加/修改
     * @param advertisers
     * @return
     */
    @PostMapping("/saveOrUpdate")
    public Result saveOrUpdate(@RequestBody Advertisers advertisers){
        advertisersService.saveOrUpdate(advertisers);
        return Result.ok();
    }

    /**
     * 删除
     * @param advertiserId
     * @return
     */
    @DeleteMapping("/delete")
    @Transactional
    public Result delete(@RequestParam Integer advertiserId) {
        // 1. 查询广告主是否存在
        Advertisers advertiser = advertisersService.getById(advertiserId);
        if (advertiser == null) {
            return Result.fail(404, "广告主不存在");
        }

        // 2. 获取该广告主下的所有广告计划ID
        List<Integer> campaignIds = adCampaignsService.findCampaignIdsByAdvertiser(advertiserId);

        // 3. 删除这些广告计划下的所有广告创意
        if (!campaignIds.isEmpty()) {
            adCreativesService.deleteByCampaignIds(campaignIds);
        }

        // 4. 删除这些广告计划
        adCampaignsService.deleteByAdvertiserId(advertiserId);

        // 5. 删除广告主
        advertisersService.removeById(advertiserId);

        return Result.ok();
    }

    @PostMapping("/updateStatus")
    @Transactional
    public Result updateStatus(@RequestParam Integer advertiserId, @RequestParam BaseStatus status) {
        // 1. 查询广告主并校验存在性
        Advertisers advertiser = advertisersService.getById(advertiserId);
        if (advertiser == null) {
            return Result.fail(201, "广告主不存在");
        }

        // 2. 判断状态是否变化
        Integer originalStatus = advertiser.getStatus();
        boolean statusChanged = !originalStatus.equals(status.getCode());

        // 3. 更新广告主状态
        boolean updateResult = advertisersService.lambdaUpdate()
                .eq(Advertisers::getAdvertiserId, advertiserId)
                .set(Advertisers::getStatus, status.getCode())
                .update();

        if (!updateResult) {
            return Result.fail(201, "广告主状态更新失败");
        }

        // 4. 执行级联操作
        if (statusChanged && status == BaseStatus.DISABLE) {
            cascadeSuspendResources(advertiserId);
        } else if (statusChanged && status == BaseStatus.ENABLE) {
            cascadeResumeResources(advertiserId);
        }

        return Result.ok();
    }

    /**
     * 级联暂停资源（广告计划+创意）
     */
    private void cascadeSuspendResources(Integer advertiserId) {
        // 1. 暂停广告计划
        List<AdCampaigns> campaigns = adCampaignsService.lambdaQuery()
                .eq(AdCampaigns::getAdvertiserId, advertiserId)
                .in(AdCampaigns::getStatus, Arrays.asList(1, 2, 3)) // 草稿/审核中/运行中
                .eq(AdCampaigns::getIsCascade, 0) // 非级联暂停
                .list();

        if (!campaigns.isEmpty()) {
            List<Integer> campaignIds = campaigns.stream()
                    .map(AdCampaigns::getCampaignId)
                    .collect(Collectors.toList());

            // 批量更新计划状态（保存原始状态）
            campaigns.forEach(campaign -> {
                campaign.setPreCascadeStatus(campaign.getStatus()); // 保存原始状态
                campaign.setStatus(4); // 暂停
                campaign.setIsCascade(1); // 标记级联操作
            });
            adCampaignsService.updateBatchById(campaigns);

            // 2. 暂停关联创意
            suspendCreativesByCampaigns(campaignIds, true);
        }
    }

    /**
     * 级联恢复资源（广告计划+创意）
     */
    private void cascadeResumeResources(Integer advertiserId) {
        // 1. 查询需要恢复的广告计划
        List<AdCampaigns> campaigns = adCampaignsService.lambdaQuery()
                .eq(AdCampaigns::getAdvertiserId, advertiserId)
                .eq(AdCampaigns::getIsCascade, 1) // 仅级联暂停过的
                .list();

        if (campaigns.isEmpty()) {
            return;
        }

        // 2. 筛选可恢复的广告计划（必须是暂停状态）
        List<AdCampaigns> campaignsToResume = campaigns.stream()
                .filter(campaign -> campaign.getStatus() == 4) // 必须是暂停状态
                .collect(Collectors.toList());

        // 3. 恢复广告计划状态
        if (!campaignsToResume.isEmpty()) {
            campaignsToResume.forEach(campaign -> {
                // 恢复原始状态（如果原始状态有效）
                if (campaign.getPreCascadeStatus() != 0 &&
                        (campaign.getPreCascadeStatus() >= 1 && campaign.getPreCascadeStatus() <= 3)) {
                    campaign.setStatus(campaign.getPreCascadeStatus());
                } else {
                    // 默认恢复为运行状态（安全回退）
                    campaign.setStatus(3);
                }
                campaign.setPreCascadeStatus(0); // 清除原始状态
                campaign.setIsCascade(0); // 清除级联标记
            });
            adCampaignsService.updateBatchById(campaignsToResume);

            // 4. 恢复关联创意
            List<Integer> campaignIds = campaignsToResume.stream()
                    .map(AdCampaigns::getCampaignId)
                    .collect(Collectors.toList());
            resumeCreativesByCampaigns(campaignIds);
        }

        // 5. 处理状态已变更的计划（不再暂停状态）
        List<AdCampaigns> modifiedCampaigns = campaigns.stream()
                .filter(campaign -> campaign.getStatus() != 4)
                .collect(Collectors.toList());

        if (!modifiedCampaigns.isEmpty()) {
            // 清除级联标记（但保留当前状态）
            modifiedCampaigns.forEach(campaign -> {
                campaign.setPreCascadeStatus(0);
                campaign.setIsCascade(0);
            });
            adCampaignsService.updateBatchById(modifiedCampaigns);

        }
    }

    /**
     * 暂停广告计划下的创意
     */
    private void suspendCreativesByCampaigns(List<Integer> campaignIds, boolean isCascade) {
        if (campaignIds.isEmpty()) return;

        adCreativesService.lambdaUpdate()
                .in(AdCreatives::getCampaignId, campaignIds)
                .eq(AdCreatives::getStatus, 1) // 只处理启用中的创意
                .eq(AdCreatives::getIsCascade, 0) // 非级联禁用状态
                .set(AdCreatives::getStatus, 0) // 暂停
                .set(AdCreatives::getIsCascade, isCascade ? 1 : 0) // 设置级联标记
                .update();
    }

    /**
     * 恢复广告计划下的创意
     */
    private void resumeCreativesByCampaigns(List<Integer> campaignIds) {
        if (campaignIds.isEmpty()) return;

        adCreativesService.lambdaUpdate()
                .in(AdCreatives::getCampaignId, campaignIds)
                .eq(AdCreatives::getStatus, 0) // 当前暂停状态
                .eq(AdCreatives::getIsCascade, 1) // 仅级联禁用的创意
                .set(AdCreatives::getStatus, 1) // 启用
                .set(AdCreatives::getIsCascade, 0) // 清除级联标记
                .update();
    }

    /**
     *查询广告主id和公司名称
     * @return
     */
    @GetMapping("/dropdown")
    public Result<List<Map<Integer, Object>>> getAdvertiser() {
        List<Map<Integer, Object>> dropdownList = advertisersService.getAdvertiser();
        return Result.ok(dropdownList);
    }
}
